#!/usr/bin/env python
# -*- coding:utf-8 -*-

from controller.userController import UserController

import datetime
import math

from flask import current_app ,make_response ,jsonify,g
from sqlalchemy import or_
from werkzeug.security import generate_password_hash, check_password_hash

from models.administratorTokenModel import AdministratorToken
from service.administratorTokenService import AdministratorTokenService

from app import db
from models.user import User
from utils import commons
from utils.generate_id import GenerateID
from utils.loggings import loggings
from utils.response_code import RET, error_map_EN
from utils.rsa_encryption_decryption import RSAEncryptionDecryption


class UserService(UserController):

    # 用户注册
    @classmethod
    def user_register(cls, **kwargs):
        # 判断用户账号是否已经存在
        try:
            user_info = db.session.query(cls).filter(
                User.user_account == kwargs.get("user_account")).filter(
                User.is_delete == 0).first()

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': '数据库异常，获取信息失败', 'data': str(e)}

        if user_info:
            return {'code': RET.DATAEXIST, 'message': '账号存在', 'data': '账号已经存在'}
        # 生成用户id
        user_id = GenerateID.create_random_id()
        # 加密密码
        rsa = RSAEncryptionDecryption()
        pass_word_text = rsa.encrypt(kwargs.get('user_password')).decode('utf-8')
        try:
            new_user = User(user_id=int(user_id),
                                              user_account=kwargs.get('user_account'),
                                              user_password=pass_word_text,
                                              user_name=kwargs.get('user_name'),
                                              is_delete=0
                                              )

            db.session.add(new_user)
            db.session.commit()

            data = commons.query_to_dict(new_user)
            data_dict = {
                'user_id': data.get('user_id'),
                'user_account': data.get('user_account'),
                'create_time': data.get('create_time'),
            }
            return {'code': RET.OK, 'message': '注册成功', 'data': data_dict}

        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': '数据库异常，添加用户失败', 'data': str(e)}
        finally:
            db.session.close()


    # 系统用户登录
    @classmethod
    def administrator_login(cls, **kwargs):

        # 校验密码
        # 读取字典中的密码
        pass_word_cipher = kwargs.get('user_password')
        # 实例化加密类
        rsa = RSAEncryptionDecryption()
        # 调用加密方法，返回加奥秘后的密码

        pass_word_text = rsa.encrypt(pass_word_cipher).decode('utf-8')
        if not pass_word_text:
            return {'code': RET.LOGINERR, 'message': '密码格式不正确', 'error': '密码格式不正确'}

        try:
            # 只是包含一个 SQLAlchemy 查询条件表达式
            filter_list = [cls.user_account == kwargs.get('user_account')]

            # 如果返回的列表为空，则返回错误
            if not filter_list:
                return {'code': RET.NODATA, 'message': '参数不完整', 'error': '参数不完整'}
            # 添加is_delete=0的条件
            filter_list.append(cls.is_delete == 0)
            user_info = db.session.query(cls).filter(*filter_list).first()
        except Exception as e:
            return {'code': RET.DBERR, 'message': '获取用户信息失败', 'error': str(e)}

        # 如果无数据，用户不存在
        if not user_info:
            return {'code': RET.NODATA, 'message': '用户不存在', 'error': '用户不存在'}
        # 如果密码错误
        if rsa.decrypt(user_info.user_password)!=pass_word_cipher:
            return {'code': RET.PWDERR, 'message': '用户名或密码错误', 'error': '用户名或密码错误'}

        # 密码验证成功，生成token
        token = AdministratorTokenService.create_token(user_info.user_id, 0)
        expire_time = (datetime.datetime.now() + datetime.timedelta(seconds=current_app.config['TOKEN_EXPIRES'])). \
            strftime('%Y-%m-%d %H:%M:%S')

        try:
            user_token = db.session.query(AdministratorToken).filter(AdministratorToken.user_id == user_info.user_id,
                                                            AdministratorToken.user_type == 0)
        except Exception as e:
            loggings.exception(1, e)

        # 首次登录
        if not user_token.first():
            kwargs = {
                'user_id': user_info.user_id,
                'token': token,
                'expire_time': expire_time,
                'user_type': 0
            }
            user_token_first = AdministratorTokenService.save_token(**kwargs)

            if not user_token_first:
                return {'code': RET.DBERR, 'message': '数据库异常，保存token数据失败',
                        'error': '数据库异常，保存token数据失败'}

        else:
            user_token.update(
                {'token': token, 'expire_time': expire_time, 'is_valid': 1})
            db.session.commit()



        data_dict = {
            'user_account': user_info.user_account,
            'user_name': user_info.user_name
        }
        # 创建响应对象
        response = make_response(jsonify({'code': RET.OK, 'message': '登录成功', 'data': data_dict}))
        # 将token放在响应头中
        response.headers['Authorization'] = f'Bearer {token}'
        return response
        # db.session.close()
        # return {'code': RET.OK, 'message': '登录成功', 'data': data_dict}


    # 用户修改密码
    @classmethod
    def modify_password(cls, **kwargs):
        # 校验旧密码
        old_pass_word_cipher = kwargs.get('old_password')
        new_pass_word_cipher = kwargs.get('new_password')

        rsa = RSAEncryptionDecryption()
        old_pass_word_text = rsa.encrypt(old_pass_word_cipher)
        new_pass_word_text = rsa.encrypt(new_pass_word_cipher)

        if not old_pass_word_text or not new_pass_word_text:
            return {'code': RET.LOGINERR, 'message': '密码格式不正确', 'data': '密码格式不正确'}

        filter_list = []

        try:
            if kwargs.get('user_id'):
                filter_list.append(cls.user_id == kwargs.get('user_id'))

            if not filter_list:
                return {'code': RET.NODATA, 'message': '参数不完整', 'data': '参数不完整'}
            filter_list.append(cls.is_delete == 0)
            user_info = db.session.query(cls).filter(*filter_list).first()
        except Exception as e:
            return {'code': RET.DBERR, 'message': '获取用户信息失败', 'data': {'error': str(e)}}
        finally:
            db.session.close()
        # 如果无数据，用户不存在
        if not user_info:
            return {'code': RET.NODATA, 'message': '用户不存在', 'data': '用户不存在'}
        # 如果密码错误
        if rsa.decrypt(user_info.user_password)!=old_pass_word_cipher:
            return {'code': RET.PWDERR, 'message': '用户名或密码错误', 'data': '用户名或密码错误'}
        # 密码正确就去更新信息
        kwargs = {
            'user_id': user_info.user_id,
            "user_password": new_pass_word_cipher
        }
        UserController.update(**kwargs)

        results = {
            'update_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            'user_id': user_info.user_id
        }
        return {'code': RET.OK, 'message': '更新成功', 'data': results}

    # 系统用户获取个人信息
    @classmethod
    def me(cls, **kwargs):
        filter_list = [cls.is_delete == 0, cls.user_id == kwargs.get('user_id')]

        try:
            info = db.session.query(
                cls.user_id,
                cls.user_name,
                cls.user_account,
                cls.user_head
            ).filter(*filter_list).first()

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

        if not info:
            return {'code': RET.NODATA, 'message': '无用户信息', 'data': '无用户信息'}
        # 处理返回的数据
        results = commons.query_to_dict(info)
        # # 模式为上传到本地
        # if current_app.config['FILE_STORE_MODE'] == 1:
        #     if results.get('head_pic'):
        #         results['head_pic'] = current_app.config['IMAGE_SERVER_DEST'] + results['head_pic']

        return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}